#pragma once

#include <vector>
#include <string>
#include <fstream>

struct long_int_t
{
   long_int_t(void);
   long_int_t(long long);
   static long_int_t zero();

   friend std::istream& operator>>(std::istream&, long_int_t&);
   friend std::ostream& operator<<(std::ostream&, const long_int_t&);

   long_int_t& operator=(const long_int_t&);

   bool operator==(const long_int_t&) const;
   bool operator!=(const long_int_t&) const;
   bool operator>(const long_int_t&) const;
   bool operator>=(const long_int_t&) const;
   bool operator<(const long_int_t&) const;
   bool operator<=(const long_int_t&) const;

   long_int_t& operator>>=(int);
   long_int_t& operator<<=(int);
   long_int_t operator>>(int);
   long_int_t operator<<(int);

   long_int_t& operator+=(const long_int_t&);
   long_int_t operator+(const long_int_t&) const;
   long_int_t& operator-=(const long_int_t&);
   long_int_t operator-(const long_int_t&) const;
   long_int_t& operator*=(long long);
   long_int_t operator*(long long) const;
   long_int_t& operator/=(const long_int_t&);
   long_int_t operator/(const long_int_t&) const;
   long_int_t& operator%=(const long_int_t&);
   long_int_t operator%(const long_int_t&) const;
   std::pair<long_int_t, long_int_t> quotient_and_remainder(const long_int_t&) const;

private:        
   int shift_;
   std::vector<long long> digits_;

   static const long long BASE = 1000000000;
   static const int BASE_LENGTH = 9;
   
   explicit long_int_t(const std::vector<long long>&);
   size_t size() const;
   void cut_zeros();
   void normalize();  

   long long compare_to(const long_int_t&) const;
   long long find_divisor(const long_int_t&) const;
};